#ifndef EVENT_H
#define EVENT_H
#include <string>
#include <ostream>
#include <cstdio>

namespace reactor {

inline void print_msg(const char * msg){
    fprintf(stderr, "%s\n", msg);
}

#define TIMEOUT_MAX_VALUE 10368000 //60 * 60 * 24 * 120
typedef int Handle;

typedef enum{
    EV_WRITE = 0x01,
    EV_READ = 0x02,
    EV_PERSIST = 0x04,
    EV_ERROR = 0x08,
    EV_TIMEOUT = 0x10
} EventType;

/// 结点内包含handle，也就是知道了handle对应的事件、时间结点
struct Node{
    int m_time;
    Handle m_handle;
    Node( long time = -1,Handle handle = -1) : m_time(time),m_handle(handle){}
    friend inline bool operator<(const Node &a, const Node &b ){
        return a.m_time < b.m_time;
    }

    friend inline std::ostream & operator<<(std::ostream & os,const Node &node){
        return os << "(" << node.m_time << "," << node.m_handle << ")";
    }

    friend inline bool operator==(const Node &a,const Node &b){
        return a.m_handle == b.m_handle;
    }
};

class Reactor;
/// 所有事件的基类，子类根据自己需求，实现具体的函数，读、写、错误、超时
///
class Event
{
protected:
    Event(Reactor *reactor,int type);    //allow called from subclass
public:
    virtual ~Event(){}
    inline Handle getHandle() { return m_handle; }
    virtual void * write(void * data);

    virtual void * read(void * data);

    virtual void * error(void * data);

    virtual void * timeout(void *data);

    void closeEvent();

    void setEventType(int event_type);
    inline int getEventType(){ return m_event_type; }

    inline void setTimeout(int t){ m_timeout = t; }
    inline int getTimeout(){ return m_timeout; }

    inline void setUpdateEvent(bool t){ m_update_time = t; }
    inline bool getUpdateEvent(){ return m_update_time; }
protected:

protected:
    Reactor * m_reactor;
    Handle m_handle;
    int m_event_type;
    int m_timeout;//seconds
    bool m_update_time;
    void * (* on_write)(void *data);
    void * (* on_read)(void *data);
    void * (* on_error)(void *data);
    void * (* on_timeout)(void *data);
};
/// 具体的继承，四个void数据段，用来传递外部的数据，可根据具体改写，比如在read（）需要使用内部的数据
/// 这里暂时都没有使用
class ServerEvent : public Event{
public:

    ServerEvent(Reactor * reactor,int type,const std::string &ip,const int &port,void * rdata=0,void *wdata=0, void *tdata=0,void *edata=0);
    virtual ~ServerEvent();
    void * read(void *data);
    void * timeout(void *data);
private:
    std::string m_ip;
    int m_port;

    void * m_r_data;
    void * m_w_data;
    void * m_t_data;
    void * m_e_data;
};

class RWEvent : public Event{
public:
    RWEvent(Reactor * reactor,int type,int handle,void * rdata=0,void *wdata=0, void *tdata=0,void *edata=0);
    virtual ~RWEvent();
    void * read(void *data);
    void * write(void *data);
    void * error(void *data);
    void *timeout(void *data);
protected:
    unsigned char *m_recv_buff;
    unsigned int m_recv_length;
    unsigned int m_recv_offset;
private:
    void * m_r_data;
    void * m_w_data;
    void * m_t_data;
    void * m_e_data;
};

}

#endif // EVENT_H
